package com.catcoin.finance.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.catcoin.finance.mapper.AccountMapper;
import com.catcoin.finance.model.*;
import com.catcoin.finance.mapper.LogPurseCorpusMapper;
import com.catcoin.finance.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.catcoin.finance.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 理财钱包本金流水 服务实现类
 * </p>
 *
 * @author baggar
 * @since 2018-09-03
 */
@Service
public class LogPurseCorpusServiceImpl extends ServiceImpl<LogPurseCorpusMapper, LogPurseCorpus> implements ILogPurseCorpusService {
    @Autowired
    private LogPurseCorpusMapper logPurseCorpusMapper;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private ISysConfigsService iSysConfigsService;
    @Autowired
    private ToolfeignInterface toolfeignInterface;
    @Autowired
    private ConsumefeignInterface consumefeignInterface;
    @Autowired
    private IAccountService iAccountService;
    @Autowired
    private ILogMailccService iLogMailccService;
    @Autowired
    private ILogBlanceccService iLogBlanceccService;
    @Autowired
    private IMoneyccService iMoneyccService;
    /**
     * 每日最高提出额度(本金百分比)
     */
    private static final String highestLimit = "highestLimit";
   /**
     *  提币到强制消费(百分比)
     */
    private static final String withdrawToForce = "withdrawToForce";
    /**
     * 提币到余额(百分比)
     */
    private static final String withdrawToBlancecc = "withdrawToBlancecc";

    @Override
    @Transactional
    public Map<String, String> exchangeToPurse(Integer userId, String shiftToSum) {
        Map<String,String> result = new HashMap<String,String>();
        //获取交易所userId
        AccountDTO accountDTO = accountMapper.selectAccountDtoByUserId(userId);
        String userIdResult = toolfeignInterface.register(accountDTO.getUserPhone());
        if("getRegisterERROR".equals(userIdResult)){
            result.put("ERROR","查询交易所用户信息失败,请稍后重试");
            return result;
        }
        String userID = null;
        if(!"error".equals(userIdResult)){
            JSONObject jsonObject = JSONObject.parseObject(userIdResult);
            if("true".equals(jsonObject.get("isSuc").toString())){
                JSONObject jsonObject1 = JSONObject.parseObject(jsonObject.get("datas").toString());
                userID = jsonObject1.get("userID").toString();
            }
        }
        if (userID==null){
            result.put("ERROR","查询用户信息失败,请稍后重试");
            return result;
        }
        if ("0".equals(userID)){
            result.put("ERROR","该用户未在交易所注册");
            return result;
        }
        //获取交易所用户余额
        //@param userID 交易所用户id     @param coinID 币种  21=HHTB,17=MAOC猫币
        String balance = toolfeignInterface.getBalance("305312", "17");
        //String balance = toolfeignInterface.getBalance(userID, "17");
        if("getBalanceERROR".equals(balance)){
            result.put("ERROR","查询可用猫币余额失败,请稍后重试");
            return result;
        }
        //初始化一个猫币余额总额
        BigDecimal total = new BigDecimal("0");
        JSONObject jsonObject = JSONObject.parseObject(balance);
        if("true".equals(jsonObject.get("isSuc").toString())){
            JSONObject jsonObject1 = JSONObject.parseObject(jsonObject.get("datas").toString());
            total = new BigDecimal(jsonObject1.get("available").toString());
        }
        BigDecimal shiftToSumTotal = new BigDecimal(shiftToSum);
        //如果转入金额大于猫币余额
        if (shiftToSumTotal.compareTo(total) == 1){
            result.put("ERROR","猫币余额不足");
            return result;
        }
        //添加本金钱包记录()
        Moneycc moneycc = new Moneycc();
        moneycc.setUserId(userId);
        moneycc.setMoneyccValue(shiftToSumTotal);
        moneycc.setCreateTime(new Date());
        if(!iMoneyccService.insert(moneycc)){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            result.put("ERROR","转入失败,请稍后重试");
            return result;
        }
        //猫币余额流水（猫币余额减少流水）
        if(!iLogBlanceccService.insertLogBlancecc(userId,moneycc.getId(), shiftToSumTotal, "1", -1, "猫币余额转入理财钱包", 1)){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            result.put("ERROR","转入失败");
            return result;
        }
        //account增加可用本金，增加钱包充值总金额,猫币余额减少   本金流水生成
        if(! this.updateAccountById(userId,shiftToSumTotal,moneycc.getId())){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            result.put("ERROR","转入失败");
            return result;
        }
        //猫币余额减少
        String operate = toolfeignInterface.operate(userID, "17", "0", shiftToSum);
        //String operate = toolfeignInterface.operate("305312", "17", "0", shiftToSum);
        if("getOperateERROR".equals(operate)){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            result.put("ERROR","猫币余额转出失败");
            return result;
        }
        JSONObject jsonObjectOperate = JSONObject.parseObject(operate);
        if("success".equals(jsonObjectOperate.get("des").toString())){
            result.put("SUCCESS","提币成功");
            return result;
        }
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        result.put("ERROR","转入失败");
        return result;
    }

    @Override
    public Boolean updateAccountById(Integer userId, BigDecimal shiftToSumTotal,Integer moneyccId) {
        //用户添加理财本金
        //添加用户本金流水
        Integer insert = this.insertLogPurseCorpus(userId, shiftToSumTotal, "1", moneyccId,1, "猫币余额转入",1);
        Account account = iAccountService.selectOne(new EntityWrapper<Account>().eq("userId", userId));
        BigDecimal moneycc = account.getMoneycc();
        //死锁了，new个新的修改
        Account account1 = new Account();
        account1.setUserId(account.getUserId());
        account1.setId(account.getId());
        account1.setMoneycc(account.getMoneycc().add(shiftToSumTotal).setScale(6,BigDecimal.ROUND_DOWN));
        account1.setMoneyccTotal(account.getMoneyccTotal().add(shiftToSumTotal).setScale(6,BigDecimal.ROUND_DOWN));
        account1.setBlancecc(account.getBlancecc().subtract(shiftToSumTotal).setScale(6,BigDecimal.ROUND_DOWN));
        boolean result = iAccountService.update(account1, new EntityWrapper<Account>().eq("userId", userId));
        if(result && 1 == insert){
            return true;
        }
        return false;
    }

    /**
     * 生成理财钱包本金流水
     * @param userId
     * @param purseCorpus  变化的数量
     * @param sign  猫币余额转入1   理财钱包提币到消费2   理财钱包提币到猫币余额3
     * @param purseAccrualType  流水标志 -1减少 1增加
     * @param setRemark 备注 猫币余额转入  理财钱包转出消费   理财钱包转出猫币余额
     * @param type 类型 1猫币余额转入  2理财钱包提币到消费  3理财钱包提币到猫币余额'
     * @return
     */
    public Integer insertLogPurseCorpus(Integer userId,BigDecimal purseCorpus,String sign,Integer moneyccId,Integer purseAccrualType,String setRemark,Integer type){
        Account account = iAccountService.selectOne(new EntityWrapper<Account>().eq("userId", userId));
        LogPurseCorpus logPurseCorpus = new LogPurseCorpus();
        logPurseCorpus.setUserId(userId);
        logPurseCorpus.setFromId(userId);
        logPurseCorpus.setOrderNo(StringUtils.getOrderIdByTime(sign));
        logPurseCorpus.setMoneyccId(moneyccId);
        logPurseCorpus.setPrePurseCorpus(account.getMoneycc());
        logPurseCorpus.setPurseCorpus(purseCorpus);
        logPurseCorpus.setPurseCorpusType(purseAccrualType);
        logPurseCorpus.setRemark(setRemark);
        logPurseCorpus.setDataFlag(1);
        logPurseCorpus.setCreateTime(new Date());
        logPurseCorpus.setType(type);
        return logPurseCorpusMapper.insert(logPurseCorpus);
    }







    @Override
    public Account purseCount(Integer userId) {
        return iAccountService.selectOne(new EntityWrapper<Account>().eq("userId", userId));
    }



    @Override
    public BigDecimal highestLimit(Integer userId) {
        //每天最高提出额为本金的10%-20%（系统计算比例）
        SysConfigs highest = iSysConfigsService.selectOne(new EntityWrapper<SysConfigs>().eq("fieldCode", highestLimit));
        Account account = iAccountService.selectOne(new EntityWrapper<Account>().eq("userId", userId));
        if(account.getMoneycc().compareTo(new BigDecimal("0"))==0){
            return null;
        }
        BigDecimal moneycc = account.getMoneycc().multiply(new BigDecimal(highest.getFieldValue()).divide(new BigDecimal("100"))).setScale(6, BigDecimal.ROUND_DOWN);
        return moneycc;
    }

    /**
     * 减少用户理财本金
     * @param userId
     * @param moneycc
     * @return
     */
    public boolean updateAccount(Integer userId,BigDecimal moneycc){
        Account account = iAccountService.selectOne(new EntityWrapper<Account>().eq("userId", userId));
        account.setMoneycc(account.getMoneycc().subtract(moneycc));
        return  iAccountService.update(account, new EntityWrapper<Account>().eq("userId", userId));
    }

    /**
     * 减少用户理财本金 增加用户消费金额 增加用户猫币余额
     * @param userId
     * @param moneycc  理财余额
     * @param mailcc  商城可消费余额
     * @param blancecc  猫币余额
     * @return
     */
    public boolean updateAccountDB(Integer userId,BigDecimal moneycc,BigDecimal mailcc,BigDecimal blancecc){
        Account account = iAccountService.selectOne(new EntityWrapper<Account>().eq("userId", userId));
        account.setMoneycc(account.getMoneycc().subtract(moneycc));
        account.setMailcc(account.getMailcc().add(mailcc));
        account.setBlancecc(account.getBlancecc().add(blancecc));
        return  iAccountService.update(account, new EntityWrapper<Account>().eq("userId", userId));
    }


    @Override
    public Map<String, Object> queryPurseCorpusLog(Integer userId) {
        Map<String,Object> purseCorpusMap = new HashMap<String,Object>();
        //猫币余额转入理财钱包本金流水
        List<Map<String,String>> logBlanceccToCorpus = logPurseCorpusMapper.LogPurseCorpusMapper(userId, 1, 1);
        //理财利息达到本金清空倍数本金清空流水
        List<Map<String,String>> logCorpusToZero = logPurseCorpusMapper.LogPurseCorpusMapper(userId, -1, 5);
        purseCorpusMap.put("猫币余额转入理财钱包本金流水",logBlanceccToCorpus);
        purseCorpusMap.put("理财利息达到本金清空倍数本金清空流水",logCorpusToZero);
        return purseCorpusMap;
    }
}
